package com.ocm.tourism.core.dao.jpa;

import java.util.List;

import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import com.ocm.tourism.core.dao.BusinessDao;
import com.ocm.tourism.core.domain.Album;
import com.ocm.tourism.core.domain.Business;
import com.ocm.tourism.core.domain.BusinessType;
import com.ocm.tourism.core.model.FieldCriteria;
import com.ocm.tourism.core.model.SearchCriteria;
import com.ocm.tourism.core.search.build.SQLBuilder;

@Repository("businessDao")
public class JpaBusinessDao extends JpaGenericDao<Business> implements BusinessDao {

   SQLBuilder sqlBuilder;

   @Autowired
   public JpaBusinessDao(@Qualifier("businessSQLBuilder")SQLBuilder sqlBuilder) {
      this.sqlBuilder = sqlBuilder;
      this.setClazz(Business.class);
   }

   @Override
   public long count(BusinessType businessType) {
      Query query = this.entityManager().createQuery("SELECT COUNT(b) FROM Business b WHERE b.businessType =:businessType", Long.class);
      query.setParameter("businessType", businessType);
      long count = (Long) query.getSingleResult();
      return count;
   }

   @SuppressWarnings("unchecked")
   public List<Business> findAll(BusinessType businessType) {
      Query query = this.entityManager().createQuery("SELECT b FROM Business b WHERE b.businessType =:businessType", Business.class);
      query.setParameter("businessType", businessType);
      List<Business> businesses = query.getResultList();
      return businesses;
   }

   @SuppressWarnings("unchecked")
   public List<Business> findAll(int firstResult, int maxResults, BusinessType businessType) {
      Query query = this.entityManager().createQuery("SELECT b FROM Business b WHERE b.businessType =:businessType", Business.class).setFirstResult(firstResult).setMaxResults(maxResults);
      query.setParameter("businessType", businessType);
      List<Business> businesses = query.getResultList();
      return businesses;
   }

   @SuppressWarnings("unchecked")
   @Override
   public Business findByPartcipantId(long id, long participantId) {
      Query query = this.entityManager().createQuery("SELECT b FROM Business b WHERE b.id=:businessId and b.participant.id =:participantId", Business.class);
      query.setParameter("businessId", id);
      query.setParameter("participantId", participantId);
      List<Business> businesses = query.getResultList();
      if (businesses.size() > 0)
         return businesses.get(0);
      return null;
   }

   @Override
   public boolean hasExisted(long id, long participantId) {
      Query query = this.entityManager().createQuery("SELECT count(b) FROM Business b WHERE b.id=:businessId and b.participant.id =:participantId", Long.class);
      query.setParameter("businessId", id);
      query.setParameter("participantId", participantId);
      Long count = (Long) query.getSingleResult();
      if (count > 0)
         return true;
      return false;
   }

   @Override
   public long count(BusinessType businessType, long participantId) {
      Query query = this.entityManager().createQuery("SELECT COUNT(b) FROM Business b WHERE b.businessType =:businessType and b.participant.id =:participantId", Long.class);
      query.setParameter("businessType", businessType);
      query.setParameter("participantId", participantId);
      long count = (Long) query.getSingleResult();
      return count;
   }

   @SuppressWarnings("unchecked")
   @Override
   public List<Business> findAll(int firstResult, int maxResults, BusinessType businessType, long participantId) {
      Query query = this.entityManager().createQuery("SELECT b FROM Business b WHERE b.businessType =:businessType and b.participant.id =:participantId", Business.class).setFirstResult(firstResult).setMaxResults(maxResults);
      query.setParameter("businessType", businessType);
      query.setParameter("participantId", participantId);
      List<Business> businesses = query.getResultList();
      return businesses;
   }

   @SuppressWarnings("unchecked")
   @Override
   public Album findByBusiness(long businessId) {
      Query query = this.entityManager().createQuery("SELECT a FROM Album a WHERE a.businessId =:businessId", Album.class);
      query.setParameter("businessId", businessId);
      List<Album> albums = query.getResultList();
      if (albums.size() > 0)
         return albums.get(0);
      return null;
   }

   @Override
   public void saveAlbum(Album album) {
      this.entityManager().persist(album);
   }

   @SuppressWarnings("unchecked")
   @Override
   public List<Business> findBusinesses(SearchCriteria searchCriteria, int firstResult, int maxResults) {
      Query query = this.entityManager().createQuery(sqlBuilder.buildSQL(searchCriteria), Business.class).setFirstResult(firstResult).setMaxResults(maxResults);
      List<FieldCriteria> criterias = searchCriteria.getFieldCriterias();
      for (FieldCriteria criteria : criterias){
         query.setParameter(criteria.getName(), criteria.getValue());
      }
      List<Business> businesses = query.getResultList();
      return businesses;
   }
}
